home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2006 April / DPPRO0406DVD.ISO / Essentials / Programming / Basic4GL / Setup Basic4GL v2.3.3.exe / $INSTDIR / Programs / ParticleDemo2.gb < prev    next >
Encoding:
Text File  |  2005-10-05  |  8.8 KB  |  236 lines

  1. ' Here's a pretty random particle demo, with coloured stars zipping 
  2. ' around a 3D city scape.
  3. '
  4. ' The key points to note are:
  5. '   * Billboarding. The stars are always drawn facing the camera (see 
  6. '     comments around the glGetFloatv(GL_MODELVIEW_MATRIX) code)
  7. '   * Interaction between solid polygon objects and transparent 
  8. '     star particles. This is done by drawing the solid objects first
  9. '     then turning off writing to the Z-buffer and drawing transparent
  10. '     ones.
  11.  
  12. ' Buildings
  13. const rows = 10, cols = 10
  14. dim heights#(rows)(cols), height#
  15.  
  16. ' Particles
  17. const particleCount = 200
  18. dim starTex
  19. type SParticle
  20.     active as integer
  21.     texture as integer  ' Texture. (We only have one texture, but a real implementation might have many different types)
  22.     pos(2) as single    ' Position
  23.     vel(2) as single    ' Velocity
  24.     col(2) as single
  25.     size as single
  26.     brightness as single
  27.     fadeRate as single
  28. end type
  29. dim particles(particleCount) as SParticle
  30.  
  31. ' Working
  32. dim i, row, col
  33. dim matrix#(3)(3)
  34.  
  35. ' Camera angle
  36. dim yaxis#, xaxis#, zoom#
  37. zoom# = 15
  38. xaxis# = 15
  39.  
  40. ' Generate random heights for buildings
  41. for row = 1 to rows
  42.     for col = 1 to cols
  43.         heights#(col)(row) = rnd()%9 + 1
  44.     next
  45. next
  46.  
  47. ' Load particle texture
  48. starTex = LoadTexture("data\star.bmp")
  49. TextMode(TEXT_OVERLAID)
  50. print"(Move the mouse around!)"
  51.  
  52. while true
  53.  
  54.     ' Render the scene
  55.     ' Clear screen
  56.     glClear(GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT)
  57.     
  58.     ' Set view position
  59.     glLoadIdentity()
  60.     glTranslatef(0, -3, -zoom#)
  61.     glRotatef(xaxis#, 1, 0, 0)
  62.     glRotatef(yaxis#, 0, 1, 0)
  63.     
  64.     ' When combining transparent objects and solid objects, we 
  65.     ' must draw the solid objects FIRST.
  66.     for col = 1 to cols
  67.         for row = 1 to rows
  68.         
  69.             ' Translate to building position
  70.             glPushMatrix()
  71.             glTranslatef((col - cols/2) * 3, 0, (row - rows/2) * 3)
  72.             
  73.             ' Draw building
  74.             height# = heights#(col)(row)
  75.             glBegin(GL_QUADS)
  76.                 glColor3f(.25, .25, .25)
  77.                 glVertex3f(-1, 0,       -1)
  78.                 glVertex3f( 1, 0,       -1)
  79.                 glVertex3f( 1, height#, -1)
  80.                 glVertex3f(-1, height#, -1)
  81.                 glVertex3f(-1, 0,        1)
  82.                 glVertex3f( 1, 0,        1)
  83.                 glVertex3f( 1, height#,  1)
  84.                 glVertex3f(-1, height#,  1)
  85.                 glColor3f(.5, .5, .5)
  86.                 glVertex3f(-1, 0,       -1)
  87.                 glVertex3f(-1, 0,        1)
  88.                 glVertex3f(-1, height#,  1)
  89.                 glVertex3f(-1, height#, -1)
  90.                 glVertex3f( 1, 0,       -1)
  91.                 glVertex3f( 1, 0,        1)
  92.                 glVertex3f( 1, height#,  1)
  93.                 glVertex3f( 1, height#, -1)
  94.                 glColor3f(.4, .4, .4)
  95.                 glVertex3f(-1, height#, -1)
  96.                 glVertex3f(-1, height#,  1)
  97.                 glVertex3f( 1, height#,  1)
  98.                 glVertex3f( 1, height#, -1)
  99.             glEnd()
  100.             
  101.             glPopMatrix()
  102.         next
  103.     next
  104.  
  105.     ' Now that the solid objects have been drawn, we can draw the 
  106.     ' transparent ones.
  107.     ' We need to change the way things are drawn a little bit though.
  108.     ' The solid objects have been drawn to the screen, but they have
  109.     ' also been drawn to the Z-Buffer. We will use this information to
  110.     ' allow particles to pass infront of and behind solid objects 
  111.     ' correctly.
  112.     ' However, we DON'T want to update the Z-buffer when we draw the
  113.     ' particles themselves, as they are see through. (The Z-buffer
  114.     ' would stop us being able to see through particles, which is 
  115.     ' incorrect.)   
  116.     glDepthMask(0)
  117.     
  118.     ' Turn on colour blending.
  119.     ' We will use simple addition of colours, as this is the easiest
  120.     ' for particle systems (other transparency models require drawing
  121.     ' objects from furthest to nearest, which would be a pain..)
  122.     glBlendFunc(GL_SRC_COLOR, GL_ONE)
  123.     glEnable(GL_BLEND)
  124.     
  125.     ' Enable textures
  126.     glEnable(GL_TEXTURE_2D)
  127.     for i = 1 to particleCount
  128.         if particles(i).active then 
  129.         
  130.             ' Translate to the particle's position
  131.             glPushMatrix()
  132.             glTranslatef(particles(i).pos(0), particles(i).pos(1), particles(i).pos(2))
  133.             
  134.             ' We are going to "billboard" the particle.
  135.             ' This means we draw the particle facing the camera.
  136.             ' If we were to draw the particle now, it would most likely
  137.             ' be facing in the wrong direction, and would appear like
  138.             ' a flat cardboard cutout.
  139.             ' We can force the particle to face the camera with a simple trick.        
  140.             ' 1. We get the current model view matrix.
  141.             '    This is the matrix in OpenGL containing all the transformations
  142.             '    (glTranslate, glRotate etc) that we've done so far.
  143.             glGetFloatv(GL_MODELVIEW_MATRIX, matrix#)
  144.             
  145.             ' 2. We clear out the rotation component by setting the 
  146.             '    first 3 columns back to an identity matrix.
  147.             matrix#(0) = vec4(1, 0, 0, 0)
  148.             matrix#(1) = vec4(0, 1, 0, 0)
  149.             matrix#(2) = vec4(0, 0, 1, 0)
  150.             
  151.             ' 3. We load it back into OpenGL, replacing the previous 
  152.             '    matrix.
  153.             glLoadMatrixf(matrix#)
  154.             ' Now anything that we draw will still be in the same 
  155.             ' position, but will be facing the camera!
  156.  
  157.             ' Setup to draw the particle
  158.             glScalef(particles(i).size, particles(i).size, 1)
  159.             glBindTexture(GL_TEXTURE_2D, particles(i).texture)
  160.             glColor3fv(particles(i).col * particles(i).brightness)
  161.             
  162.             ' Draw the particle as a textured square quad
  163.             glBegin(GL_QUADS)
  164.                 glTexCoord2f(0, 0): glVertex2f(-1, -1)
  165.                 glTexCoord2f(1, 0): glVertex2f( 1, -1)
  166.                 glTexCoord2f(1, 1): glVertex2f( 1,  1)
  167.                 glTexCoord2f(0, 1): glVertex2f(-1,  1)
  168.             glEnd()
  169.             glPopMatrix()
  170.         endif
  171.     next
  172.     
  173.     ' Restore OpenGL state ready to draw the solid objects
  174.     ' in the next frame.
  175.     glDepthMask(1)
  176.     glDisable(GL_BLEND)
  177.     glDisable(GL_TEXTURE_2D)
  178.     
  179.     DrawText()
  180.     SwapBuffers()
  181.     
  182.     ' Update the camera position
  183.     xaxis# = xaxis# + mouse_yd() * 50
  184.     yaxis# = yaxis# + mouse_xd() * 50
  185.     zoom# = zoom# - mouse_wheel()     
  186.     if xaxis# < 0 then xaxis# = 0
  187.     elseif xaxis# > 90 then xaxis# = 90
  188.     endif
  189.     if zoom# < 1 then zoom# = 1 endif
  190.     
  191.     ' Animate particles
  192.     while SyncTimer(10)
  193.         
  194.         ' Generate new particles
  195.         if rnd() % 1 = 0 then
  196.             i = rnd() % particleCount + 1
  197.             if not particles(i).active then
  198.                 particles(i).active = true
  199.                 particles(i).texture = starTex
  200.                 particles(i).pos = vec3((rnd()%2001-1000)/1000.0, (rnd()%2001-1000)/1000.0, (rnd()%2001-1000)/1000.0) * 15
  201.                 particles(i).vel = vec3((rnd()%2001-1000)/1000.0, (rnd()%2001-1000)/1000.0, (rnd()%2001-1000)/1000.0) * .04
  202.                 particles(i).col = vec3((rnd()%2001     )/1000.0, (rnd()%2001     )/1000.0, (rnd()%2001     )/1000.0)
  203.                 particles(i).size = (rnd()%1000) / 1000.0
  204.                 particles(i).brightness = 2
  205.                 particles(i).faderate = 0.01
  206.             endif
  207.         endif
  208.         
  209.         ' Animate active particles
  210.         for i = 1 to particleCount
  211.             if particles(i).active then
  212.             
  213.                 ' This is a very simple particle engine.
  214.                 ' Particles simply move at a constant speed and fade out.
  215.                 ' A fuller implementation might have various different
  216.                 ' types of particles that behave in various different ways.
  217.                 ' Some examples:
  218.                 '   * Particles that are accellerated down by gravity
  219.                 '   * Smoke particles expand as they fade out
  220.                 '   * Particles that don't fade out (or don't fade out
  221.                 '     linearly)
  222.                 '   * Animated particles (with different textures
  223.                 '     for different stages of the animation.)
  224.                 particles(i).pos = particles(i).pos + particles(i).vel
  225.                 particles(i).brightness = particles(i).brightness - particles(i).faderate
  226.                 if particles(i).pos(1) < 0 then
  227.                     particles(i).pos(1) = 0
  228.                     particles(i).vel(1) = abs(particles(i).vel(1))
  229.                 endif
  230.                 if particles(i).brightness < 0 then
  231.                     particles(i).active = false
  232.                 endif
  233.             endif
  234.         next
  235.     wend
  236. wend